import { RenderTab } from './render';
import { Style } from './css';
import { names } from './css/names';
import { getSelector, generateUniqueData } from "./helper";
import type { 
    IEaseTabsInitOptions, 
    ITab, 
    IEaseTabsOptions,
    ITabRemoveParamsReturn,
    ITabChangeParamsReturn,
} from '../types/index';

const config = {
    theme: {
        classPrefix: "ease",
        tabTextColor: "#333", // tab内文字颜色
        default: "#dee1e6", // 默认色，（背景）
        wrapBottomColor: "#fff",
        splitBorderColor: "#ccc",
        splitBorderOverColor: "#1677ff",
        closeIcon: "",
        loadingIcon: "",

        focusTabBackgroundColor: "#fff",
        overTabBackgroundColor: "#e8eaed",
        focusTabTextColor: "#333"
    }
}

export class EaseTabs {
    static instance: EaseTabs;
    static EaseTabsInstance(opts: IEaseTabsOptions) {
        if (EaseTabs.instance) {
            return EaseTabs.instance;
        }
        EaseTabs.instance = new EaseTabs(opts);
        return EaseTabs.instance;
    }
    renderTab: RenderTab | undefined;
    names: ReturnType<typeof names>;
    theme: typeof config.theme;
    container: IEaseTabsInitOptions['container'];
    fixed = false; 
    toolTipKeys;
    onAdd: ((tab: ITab) => Promise<void>) | undefined;
    onRemove: ((tab: ITabRemoveParamsReturn) => Promise<void>) | undefined;
    onChange: ((tab: ITabChangeParamsReturn) => Promise<void>) | undefined;
    constructor(opts: IEaseTabsOptions) {
        this.names = names(opts?.theme?.classPrefix || config.theme.classPrefix);
        this.fixed = opts.fixed!;
        this.toolTipKeys = opts.toolTipKeys;
        this.theme = Object.assign({}, config.theme, opts?.theme || {});
        new Style(this);
    }

    init(opts: IEaseTabsInitOptions) {
        this.container = getSelector(opts.container);
        if (!this.renderTab) {
            this.renderTab = new RenderTab(this);
            this.renderTab.init(opts.initTabs);
            this.renderTab.eventBind();
        }
    }

    on(type: "add" | "remove" | "change", fn: any) {
        switch(type) {
            case "add": {
                this.onAdd = fn;
                break;
            }
            case "remove": {
                this.onRemove = fn;
                break;
            }
            case "change": {
                this.onChange = fn;
                break;
            }
        }
    }


    getFocusIndex() {
        return this.renderTab!.findFocusIndex();
    }

    async addTab(item: ITab){
        if (!item.id) {
            const id = generateUniqueData();
            item.id = id;
        }
        this.renderTab!.addTab(item);
        this.onAdd && await this.onAdd(item);
    }

    async remove(index: number){
        if (this.fixed && index == 0) {
            return;
        } 
        const { focusTab, removeTab } = await this.renderTab!.toRemoveTab(index);
        this.onRemove && await this.onRemove({ focusTab, removeTab });
    }

    async change(index: number) {
        const res = await this.renderTab!.changeFocus(index);
        if (res) {
            const { focusTab, preTab } = res;
            this.onChange && await this.onChange({ focusTab, preTab });
        }
    }
}
